home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / sv_game.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-13  |  8.6 KB  |  398 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // sv_game.c -- interface to the game dll
  21.  
  22. #include "server.h"
  23.  
  24. game_export_t    *ge;
  25.  
  26.  
  27. /*
  28. ===============
  29. PF_Unicast
  30.  
  31. Sends the contents of the mutlicast buffer to a single client
  32. ===============
  33. */
  34. void PF_Unicast (edict_t *ent, qboolean reliable)
  35. {
  36.     int        p;
  37.     client_t    *client;
  38.  
  39.     if (!ent)
  40.         return;
  41.  
  42.     p = NUM_FOR_EDICT(ent);
  43.     if (p < 1 || p > maxclients->value)
  44.         return;
  45.  
  46.     client = svs.clients + (p-1);
  47.  
  48.     if (reliable)
  49.         SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize);
  50.     else
  51.         SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize);
  52.  
  53.     SZ_Clear (&sv.multicast);
  54. }
  55.  
  56.  
  57. /*
  58. ===============
  59. PF_dprintf
  60.  
  61. Debug print to server console
  62. ===============
  63. */
  64. void PF_dprintf (char *fmt, ...)
  65. {
  66.     char        msg[1024];
  67.     va_list        argptr;
  68.     
  69.     va_start (argptr,fmt);
  70.     vsprintf (msg, fmt, argptr);
  71.     va_end (argptr);
  72.  
  73.     Com_Printf ("%s", msg);
  74. }
  75.  
  76.  
  77. /*
  78. ===============
  79. PF_cprintf
  80.  
  81. Print to a single client
  82. ===============
  83. */
  84. void PF_cprintf (edict_t *ent, int level, char *fmt, ...)
  85. {
  86.     char        msg[1024];
  87.     va_list        argptr;
  88.     int            n;
  89.  
  90.     if (ent)
  91.     {
  92.         n = NUM_FOR_EDICT(ent);
  93.         if (n < 1 || n > maxclients->value)
  94.             Com_Error (ERR_DROP, "cprintf to a non-client");
  95.     }
  96.  
  97.     va_start (argptr,fmt);
  98.     vsprintf (msg, fmt, argptr);
  99.     va_end (argptr);
  100.  
  101.     if (ent)
  102.         SV_ClientPrintf (svs.clients+(n-1), level, "%s", msg);
  103.     else
  104.         Com_Printf ("%s", msg);
  105. }
  106.  
  107.  
  108. /*
  109. ===============
  110. PF_centerprintf
  111.  
  112. centerprint to a single client
  113. ===============
  114. */
  115. void PF_centerprintf (edict_t *ent, char *fmt, ...)
  116. {
  117.     char        msg[1024];
  118.     va_list        argptr;
  119.     int            n;
  120.     
  121.     n = NUM_FOR_EDICT(ent);
  122.     if (n < 1 || n > maxclients->value)
  123.         return;    // Com_Error (ERR_DROP, "centerprintf to a non-client");
  124.  
  125.     va_start (argptr,fmt);
  126.     vsprintf (msg, fmt, argptr);
  127.     va_end (argptr);
  128.  
  129.     MSG_WriteByte (&sv.multicast,svc_centerprint);
  130.     MSG_WriteString (&sv.multicast,msg);
  131.     PF_Unicast (ent, true);
  132. }
  133.  
  134.  
  135. /*
  136. ===============
  137. PF_error
  138.  
  139. Abort the server with a game error
  140. ===============
  141. */
  142. void PF_error (char *fmt, ...)
  143. {
  144.     char        msg[1024];
  145.     va_list        argptr;
  146.     
  147.     va_start (argptr,fmt);
  148.     vsprintf (msg, fmt, argptr);
  149.     va_end (argptr);
  150.  
  151.     Com_Error (ERR_DROP, "Game Error: %s", msg);
  152. }
  153.  
  154.  
  155. /*
  156. =================
  157. PF_setmodel
  158.  
  159. Also sets mins and maxs for inline bmodels
  160. =================
  161. */
  162. void PF_setmodel (edict_t *ent, char *name)
  163. {
  164.     int        i;
  165.     cmodel_t    *mod;
  166.  
  167.     if (!name)
  168.         Com_Error (ERR_DROP, "PF_setmodel: NULL");
  169.  
  170.     i = SV_ModelIndex (name);
  171.         
  172. //    ent->model = name;
  173.     ent->s.modelindex = i;
  174.  
  175. // if it is an inline model, get the size information for it
  176.     if (name[0] == '*')
  177.     {
  178.         mod = CM_InlineModel (name);
  179.         VectorCopy (mod->mins, ent->mins);
  180.         VectorCopy (mod->maxs, ent->maxs);
  181.         SV_LinkEdict (ent);
  182.     }
  183.  
  184. }
  185.  
  186. /*
  187. ===============
  188. PF_Configstring
  189.  
  190. ===============
  191. */
  192. void PF_Configstring (int index, char *val)
  193. {
  194.     if (index < 0 || index >= MAX_CONFIGSTRINGS)
  195.         Com_Error (ERR_DROP, "configstring: bad index %i\n", index);
  196.  
  197.     if (!val)
  198.         val = "";
  199.  
  200.     // change the string in sv
  201.     strcpy (sv.configstrings[index], val);
  202.  
  203.     
  204.     if (sv.state != ss_loading)
  205.     {    // send the update to everyone
  206.         SZ_Clear (&sv.multicast);
  207.         MSG_WriteChar (&sv.multicast, svc_configstring);
  208.         MSG_WriteShort (&sv.multicast, index);
  209.         MSG_WriteString (&sv.multicast, val);
  210.  
  211.         SV_Multicast (vec3_origin, MULTICAST_ALL_R);
  212.     }
  213. }
  214.  
  215.  
  216.  
  217. void PF_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);}
  218. void PF_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);}
  219. void PF_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);}
  220. void PF_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);}
  221. void PF_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);}
  222. void PF_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);}
  223. void PF_WritePos (vec3_t pos) {MSG_WritePos (&sv.multicast, pos);}
  224. void PF_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);}
  225. void PF_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);}
  226.  
  227.  
  228. /*
  229. =================
  230. PF_inPVS
  231.  
  232. Also checks portalareas so that doors block sight
  233. =================
  234. */
  235. qboolean PF_inPVS (vec3_t p1, vec3_t p2)
  236. {
  237.     int        leafnum;
  238.     int        cluster;
  239.     int        area1, area2;
  240.     byte    *mask;
  241.  
  242.     leafnum = CM_PointLeafnum (p1);
  243.     cluster = CM_LeafCluster (leafnum);
  244.     area1 = CM_LeafArea (leafnum);
  245.     mask = CM_ClusterPVS (cluster);
  246.  
  247.     leafnum = CM_PointLeafnum (p2);
  248.     cluster = CM_LeafCluster (leafnum);
  249.     area2 = CM_LeafArea (leafnum);
  250.     if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
  251.         return false;
  252.     if (!CM_AreasConnected (area1, area2))
  253.         return false;        // a door blocks sight
  254.     return true;
  255. }
  256.  
  257.  
  258. /*
  259. =================
  260. PF_inPHS
  261.  
  262. Also checks portalareas so that doors block sound
  263. =================
  264. */
  265. qboolean PF_inPHS (vec3_t p1, vec3_t p2)
  266. {
  267.     int        leafnum;
  268.     int        cluster;
  269.     int        area1, area2;
  270.     byte    *mask;
  271.  
  272.     leafnum = CM_PointLeafnum (p1);
  273.     cluster = CM_LeafCluster (leafnum);
  274.     area1 = CM_LeafArea (leafnum);
  275.     mask = CM_ClusterPHS (cluster);
  276.  
  277.     leafnum = CM_PointLeafnum (p2);
  278.     cluster = CM_LeafCluster (leafnum);
  279.     area2 = CM_LeafArea (leafnum);
  280.     if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
  281.         return false;        // more than one bounce away
  282.     if (!CM_AreasConnected (area1, area2))
  283.         return false;        // a door blocks hearing
  284.  
  285.     return true;
  286. }
  287.  
  288. void PF_StartSound (edict_t *entity, int channel, int sound_num, float volume,
  289.     float attenuation, float timeofs)
  290. {
  291.     if (!entity)
  292.         return;
  293.     SV_StartSound (NULL, entity, channel, sound_num, volume, attenuation, timeofs);
  294. }
  295.  
  296. //==============================================
  297.  
  298. /*
  299. ===============
  300. SV_ShutdownGameProgs
  301.  
  302. Called when either the entire server is being killed, or
  303. it is changing to a different game directory.
  304. ===============
  305. */
  306. void SV_ShutdownGameProgs (void)
  307. {
  308.     if (!ge)
  309.         return;
  310.     ge->Shutdown ();
  311.     Sys_UnloadGame ();
  312.     ge = NULL;
  313. }
  314.  
  315. /*
  316. ===============
  317. SV_InitGameProgs
  318.  
  319. Init the game subsystem for a new map
  320. ===============
  321. */
  322. void SCR_DebugGraph (float value, int color);
  323.  
  324. void SV_InitGameProgs (void)
  325. {
  326.     game_import_t    import;
  327.  
  328.     // unload anything we have now
  329.     if (ge)
  330.         SV_ShutdownGameProgs ();
  331.  
  332.  
  333.     // load a new game dll
  334.     import.multicast = SV_Multicast;
  335.     import.unicast = PF_Unicast;
  336.     import.bprintf = SV_BroadcastPrintf;
  337.     import.dprintf = PF_dprintf;
  338.     import.cprintf = PF_cprintf;
  339.     import.centerprintf = PF_centerprintf;
  340.     import.error = PF_error;
  341.  
  342.     import.linkentity = SV_LinkEdict;
  343.     import.unlinkentity = SV_UnlinkEdict;
  344.     import.BoxEdicts = SV_AreaEdicts;
  345.     import.trace = SV_Trace;
  346.     import.pointcontents = SV_PointContents;
  347.     import.setmodel = PF_setmodel;
  348.     import.inPVS = PF_inPVS;
  349.     import.inPHS = PF_inPHS;
  350.     import.Pmove = Pmove;
  351.  
  352.     import.modelindex = SV_ModelIndex;
  353.     import.soundindex = SV_SoundIndex;
  354.     import.imageindex = SV_ImageIndex;
  355.  
  356.     import.configstring = PF_Configstring;
  357.     import.sound = PF_StartSound;
  358.     import.positioned_sound = SV_StartSound;
  359.  
  360.     import.WriteChar = PF_WriteChar;
  361.     import.WriteByte = PF_WriteByte;
  362.     import.WriteShort = PF_WriteShort;
  363.     import.WriteLong = PF_WriteLong;
  364.     import.WriteFloat = PF_WriteFloat;
  365.     import.WriteString = PF_WriteString;
  366.     import.WritePosition = PF_WritePos;
  367.     import.WriteDir = PF_WriteDir;
  368.     import.WriteAngle = PF_WriteAngle;
  369.  
  370.     import.TagMalloc = Z_TagMalloc;
  371.     import.TagFree = Z_Free;
  372.     import.FreeTags = Z_FreeTags;
  373.  
  374.     import.cvar = Cvar_Get;
  375.     import.cvar_set = Cvar_Set;
  376.     import.cvar_forceset = Cvar_ForceSet;
  377.  
  378.     import.argc = Cmd_Argc;
  379.     import.argv = Cmd_Argv;
  380.     import.args = Cmd_Args;
  381.     import.AddCommandString = Cbuf_AddText;
  382.  
  383.     import.DebugGraph = SCR_DebugGraph;
  384.     import.SetAreaPortalState = CM_SetAreaPortalState;
  385.     import.AreasConnected = CM_AreasConnected;
  386.  
  387.     ge = (game_export_t *)Sys_GetGameAPI (&import);
  388.  
  389.     if (!ge)
  390.         Com_Error (ERR_DROP, "failed to load game DLL");
  391.     if (ge->apiversion != GAME_API_VERSION)
  392.         Com_Error (ERR_DROP, "game is version %i, not %i", ge->apiversion,
  393.         GAME_API_VERSION);
  394.  
  395.     ge->Init ();
  396. }
  397.  
  398.